package com.lvhr.rpc.fault.tolerant;

import com.lvhr.rpc.spi.SpiLoader;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 容错策略工厂
 */
public class TolerantStrategyFactory {

    /**
     * 实例缓存
     */
    private static final ConcurrentHashMap<String, TolerantStrategy> INSTANCE_CACHE = new ConcurrentHashMap<>();

    /**
     * 默认容错策略
     */
    private static final String DEFAULT_TOLERANT_STRATEGY = "failFast";



    /**
     * 获取重试器类型实例（懒加载 + 线程安全）
     *
     * @param key 容错策略类型
     * @return 容错类型实例
     * @throws IllegalArgumentException 类型不存在时抛出
     */
    public static TolerantStrategy getInstance(String key) {
        // 参数校验
        if (key == null || key.isEmpty()) {
            key = DEFAULT_TOLERANT_STRATEGY;
        }

        // 双重校验锁实现懒加载
        return INSTANCE_CACHE.computeIfAbsent(key, t -> {
            synchronized (TolerantStrategyFactory.class) {
                // 再次检查防止其他线程已创建
                if (INSTANCE_CACHE.containsKey(t)) {
                    return INSTANCE_CACHE.get(t);
                }

                // 通过 SPI 加载实例
                TolerantStrategy instance = SpiLoader.getInstance(TolerantStrategy.class,t);
                if (instance == null) {
                    throw new IllegalArgumentException("Unsupported TolerantStrategy  : " + t);
                }
                return instance;
            }
        });
    }

    /**
     * 获取默认重试器类型实例
     */
    public static TolerantStrategy getDefaultInstance() {
        return getInstance(DEFAULT_TOLERANT_STRATEGY);
    }

}